package com.java;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 计算类
 *
 * @author chen52
 */
public class Calculator {

    // 记录当前可以操作的数的栈
    private Stack<String> numbers = new Stack<>();
    // 记录栈数据的操作日志
    private Stack<List<String>> logList = new Stack<>();

    /**
     * 计算入口
     * @param expression
     * @throws Exception
     */
    public void doExpression(String expression) throws ExpressionFormatException {

        // 通过空格分隔切分输入的表达式
        String[] strToArr = expression.split(" ");

        int strArrLenth = strToArr.length;
        CalculatorUtils calculatorUtils = new CalculatorUtils();

        for (int i = 0; i < strArrLenth; i++) {
            String operator = strToArr[i];
            //记录数字
            if (calculatorUtils.isNumber(operator)) {
                numbers.push(operator);
                addLogList(numbers, logList);
                continue;
            }

            switch (operator){
                //加减乘除
                case "+":
                case "-":
                case "*":
                case "/":

                    if (numbers.size() > 1) {
                        calculatorUtils.calculate(numbers, operator);
                        addLogList(numbers, logList);
                    } else {
                        System.out.print("参数 " + operator + " (位置: " + (i * 2 + 1) + "): 参数有误 \n");
                        break;
                    }

                    break;

                case "sqrt"://开方
                    if (numbers.size() > 0) {
                        calculatorUtils.sqrt( numbers, operator);
                        addLogList(numbers, logList);
                    } else {
                        System.out.print("参数 " + operator + " (位置: " + (i * 2 + 1) + "): 参数有误 \n");
                        break;
                    }
                    break;
                case "undo"://撤销
                    calculatorUtils.undo(numbers, logList, operator);
                    break;
                case "clear"://清除
                    calculatorUtils.clear(numbers, logList, operator);
                    break;

                 default :
//                     System.out.println("---输入的表达式有误--\n");
                        throw new ExpressionFormatException("输入的表达式有误");


            }


        }

        printStack(numbers);
    }

    /**
     * 将操作数栈的里数据 记录的日志栈中
     * @param numbers
     * @param logList
     */
    private void addLogList(Stack<String> numbers, Stack<List<String>> logList) {
        List<String> numbersList = new ArrayList<>();
        for (String d : numbers) {
            numbersList.add(d);
        }
        logList.push(numbersList);
    }

    /**
     * 打印栈数据
     * @param numbers
     */
    private void printStack(Stack<String> numbers) {
        System.out.print("stack： ");
        if(!numbers.isEmpty()) {
            for(String d : numbers) {
                System.out.print(d + " ");
            }
        }
        System.out.println();
    }

    /**
     * 精度至少为15位小数，但是显示10位小数
     * @param number
     * @return
     */
    private String numberFormat(double number) {
        DecimalFormat numFormat = new DecimalFormat("##########.##########");
        numFormat.setRoundingMode(RoundingMode.DOWN);// 舍去末尾
        String output = numFormat.format(number);
        return output;
    }
}